package com.xf.auth.service.impl.member;


import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.xf.auth.exception.FebsException;
import com.xf.common.core.authe.feign.UserConsumer;
import com.xf.common.core.domain.DmpResult;
import com.xf.common.core.entity.dmp.RegisterUserDto;
import com.xf.common.core.entity.system.SystemUser;
import com.xf.common.core.enums.AuthenticationMethodEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * 手机号或者微信小程序用户认证服务
 */
@Service("memberUserDetailsService")
@RequiredArgsConstructor
public class MemberUserDetailsServiceImpl implements UserDetailsService {

    private final UserConsumer userManager;
//    private final PasswordEncoder passwordEncoder;


    @Override
    public UserDetails loadUserByUsername(String username) {
        return null;
    }


    /**
     * 手机号码认证方式
     *
     * @param mobile
     * @return
     */
    public UserDetails loadUserByMobile(String mobile) {
        MemberUserDetails userDetails = null;
        DmpResult<SystemUser> dmpResult = userManager.findByMobile(mobile);
        signUp(dmpResult, mobile, null);
        if (null != dmpResult && null != dmpResult.getData()) {
            SystemUser systemUser = dmpResult.getData();
            MemberAuthDTO member = new MemberAuthDTO(systemUser.getUserCode(), systemUser.getUserName(), systemUser.getState());
            userDetails = new MemberUserDetails(member);
            // 认证方式：手机短信
            userDetails.setAuthenticationMethod(AuthenticationMethodEnum.MOBILE.getValue());
        }
        if (userDetails == null) {
            throw new UsernameNotFoundException("用户不存在!");
        } else if (!userDetails.isEnabled()) {
            throw new DisabledException("该账户已被禁用!");
        } else if (!userDetails.isAccountNonLocked()) {
            throw new LockedException("该账号已被锁定!");
        } else if (!userDetails.isAccountNonExpired()) {
            throw new AccountExpiredException("该账号已过期!");
        }
        return userDetails;
    }

    /**
     * 根据手机号注册新用户
     * 手机用户不存在。短信验证通过了。自动注册
     *
     * @return
     */
    public DmpResult<SystemUser> signUp(DmpResult<SystemUser> dmpResult, String mobile, String openId) {
        if (null != dmpResult && null != dmpResult.getData()) {
            return dmpResult;
        }
        //手机号定义为不需要密码。随机一个
//        String encryptPassword = passwordEncoder.encode(IdWorker.getIdStr());
        String encryptPassword = IdWorker.getIdStr();

        RegisterUserDto registerUserDto = new RegisterUserDto();
        registerUserDto.setUsername(mobile);
        registerUserDto.setTelPhone(mobile);
        registerUserDto.setPassword(encryptPassword);
        registerUserDto.setOpenId(openId);

        DmpResult<SystemUser> userDmpResult = this.userManager.registUser(registerUserDto);
        if (userDmpResult == null || userDmpResult.getData() == null) {
            throw new FebsException("该用户名已注册失败！");
        }
        return userDmpResult;
    }


    /**
     * openid 认证方式
     *
     * @param openId
     * @return
     */
    public UserDetails loadUserByOpenId(String openId) {
        MemberUserDetails userDetails = null;
        DmpResult<SystemUser> dmpResult = userManager.findByName(openId);
        signUp(dmpResult, null, openId);
        if (null != dmpResult && null != dmpResult.getData()) {
            SystemUser systemUser = dmpResult.getData();
            MemberAuthDTO member = new MemberAuthDTO(systemUser.getUserCode(), systemUser.getUserName(), systemUser.getState());
            userDetails = new MemberUserDetails(member);
            // 认证方式：手机短信
            userDetails.setAuthenticationMethod(AuthenticationMethodEnum.OPENID.getValue());// 认证方式：OpenId
        }
        if (userDetails == null) {
            throw new UsernameNotFoundException("用户不存在!");
        } else if (!userDetails.isEnabled()) {
            throw new DisabledException("该账户已被禁用!");
        } else if (!userDetails.isAccountNonLocked()) {
            throw new LockedException("该账号已被锁定!");
        } else if (!userDetails.isAccountNonExpired()) {
            throw new AccountExpiredException("该账号已过期!");
        }
        return userDetails;
    }
}
